home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / usenet / volume11 / tinymud2 / part07 < prev    next >
Encoding:
Internet Message Format  |  1990-08-10  |  55.6 KB

  1. Path: uunet!zephyr.ens.tek.com!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v11i011:  tinymud2 - user-extendible multi-user adventure (v1.5.4), Part07/10
  5. Message-ID: <6056@tekred.CNA.TEK.COM>
  6. Date: 30 Jul 90 16:46:06 GMT
  7. Sender: news@tekred.CNA.TEK.COM
  8. Lines: 2237
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: James Aspnes <asp@cs.cmu.edu>
  12. Posting-number: Volume 11, Issue 11
  13. Archive-name: tinymud2/Part07
  14. Supersedes: tinymud: Volume 8, Issue 80-83
  15.  
  16.  
  17.  
  18. #! /bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 7 (of 10)."
  25. # Contents:  db.c game.c restart-cmu tinymud.tex
  26. # Wrapped by billr@saab on Fri Jul 27 15:27:48 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'db.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'db.c'\"
  30. else
  31. echo shar: Extracting \"'db.c'\" \(9028 characters\)
  32. sed "s/^X//" >'db.c' <<'END_OF_FILE'
  33. X#include "copyright.h"
  34. X
  35. X#include <stdio.h>
  36. X#include <ctype.h>
  37. X
  38. X#include "db.h"
  39. X#include "config.h"
  40. X
  41. Xstruct object *db = 0;
  42. Xdbref db_top = 0;
  43. X
  44. X#ifdef TEST_MALLOC
  45. Xint malloc_count = 0;
  46. X#endif /* TEST_MALLOC */
  47. X
  48. X#ifndef DB_INITIAL_SIZE
  49. X#define DB_INITIAL_SIZE 10000
  50. X#endif /* DB_INITIAL_SIZE */
  51. X
  52. X#ifdef DB_DOUBLING
  53. X
  54. Xdbref db_size = DB_INITIAL_SIZE;
  55. X#endif /* DB_DOUBLING */
  56. X
  57. Xconst char *alloc_string(const char *string)
  58. X{
  59. X    char *s;
  60. X
  61. X    /* NULL, "" -> NULL */
  62. X    if(string == 0 || *string == '\0') return 0;
  63. X
  64. X    if((s = (char *) malloc(strlen(string)+1)) == 0) {
  65. X    abort();
  66. X    }
  67. X    strcpy(s, string);
  68. X    return s;
  69. X}
  70. X
  71. X#ifdef DB_DOUBLING
  72. X
  73. Xstatic void db_grow(dbref newtop)
  74. X{
  75. X    struct object *newdb;
  76. X
  77. X    if(newtop > db_top) {
  78. X    db_top = newtop;
  79. X    if(!db) {
  80. X        /* make the initial one */
  81. X        db_size = DB_INITIAL_SIZE;
  82. X        if((db = (struct object *)
  83. X        malloc(db_size * sizeof(struct object))) == 0) {
  84. X        abort();
  85. X        }
  86. X    }
  87. X    
  88. X    /* maybe grow it */
  89. X    if(db_top > db_size) {
  90. X        /* make sure it's big enough */
  91. X        while(db_top > db_size) db_size *= 2;
  92. X        if((newdb = (struct object *)
  93. X        realloc((void *) db,
  94. X            db_size * sizeof(struct object))) == 0) {
  95. X        abort();
  96. X        } 
  97. X        db = newdb;
  98. X    }
  99. X    }
  100. X}
  101. X
  102. X#else /* DB_DOUBLING */
  103. X
  104. Xstatic void db_grow(dbref newtop)
  105. X{
  106. X    struct object *newdb;
  107. X
  108. X    if(newtop > db_top) {
  109. X    db_top = newtop;
  110. X    if(db) {
  111. X        if((newdb = (struct object *)
  112. X        realloc((void *) db,
  113. X            db_top * sizeof(struct object))) == 0) {
  114. X        abort();
  115. X        } 
  116. X        db = newdb;
  117. X    } else {
  118. X        /* make the initial one */
  119. X        if((db = (struct object *)
  120. X        malloc(DB_INITIAL_SIZE * sizeof(struct object))) == 0) {
  121. X        abort();
  122. X        }
  123. X    }
  124. X    }
  125. X}
  126. X#endif /* DB_DOUBLING */
  127. X
  128. Xdbref new_object(void)
  129. X{
  130. X    dbref newobj;
  131. X    struct object *o;
  132. X
  133. X    newobj = db_top;
  134. X    db_grow(db_top + 1);
  135. X
  136. X    /* clear it out */
  137. X    o = db+newobj;
  138. X    o->name = 0;
  139. X    o->description = 0;
  140. X    o->location = NOTHING;
  141. X    o->contents = NOTHING;
  142. X    o->exits = NOTHING;
  143. X    o->next = NOTHING;
  144. X    o->key = TRUE_BOOLEXP;
  145. X    o->fail_message = 0;
  146. X    o->succ_message = 0;
  147. X    o->ofail = 0;
  148. X    o->osuccess = 0;
  149. X    o->owner = NOTHING;
  150. X    o->pennies = 0;
  151. X    /* flags you must initialize yourself */
  152. X    o->password = 0;
  153. X
  154. X    return newobj;
  155. X}
  156. X    
  157. X#define DB_MSGLEN 512
  158. X
  159. Xvoid putref(FILE *f, dbref ref)
  160. X{
  161. X    fprintf(f, "%d\n", ref);
  162. X}
  163. X
  164. Xstatic void putstring(FILE *f, const char *s)
  165. X{
  166. X    if(s) {
  167. X    fputs(s, f);
  168. X    } 
  169. X    putc('\n', f);
  170. X}
  171. X    
  172. Xstatic void putbool_subexp(FILE *f, struct boolexp *b)
  173. X{
  174. X    switch(b->type) {
  175. X      case BOOLEXP_AND:
  176. X    putc('(', f);
  177. X    putbool_subexp(f, b->sub1);
  178. X    putc(AND_TOKEN, f);
  179. X    putbool_subexp(f, b->sub2);
  180. X    putc(')', f);
  181. X    break;
  182. X      case BOOLEXP_OR:
  183. X    putc('(', f);
  184. X    putbool_subexp(f, b->sub1);
  185. X    putc(OR_TOKEN, f);
  186. X    putbool_subexp(f, b->sub2);
  187. X    putc(')', f);
  188. X    break;
  189. X      case BOOLEXP_NOT:
  190. X    putc('(', f);
  191. X    putc(NOT_TOKEN, f);
  192. X    putbool_subexp(f, b->sub1);
  193. X    putc(')', f);
  194. X    break;
  195. X      case BOOLEXP_CONST:
  196. X    fprintf(f, "%d", b->thing);
  197. X    break;
  198. X      default:
  199. X    break;
  200. X    }
  201. X}
  202. X
  203. Xvoid putboolexp(FILE *f, struct boolexp *b)
  204. X{
  205. X    if(b != TRUE_BOOLEXP) {
  206. X    putbool_subexp(f, b);
  207. X    }
  208. X    putc('\n', f);
  209. X}
  210. X    
  211. Xint db_write_object(FILE *f, dbref i)
  212. X{
  213. X    struct object *o;
  214. X
  215. X    o = db + i;
  216. X    putstring(f, o->name);
  217. X    putstring(f, o->description);
  218. X    putref(f, o->location);
  219. X    putref(f, o->contents);
  220. X    putref(f, o->exits);
  221. X    putref(f, o->next);
  222. X    putboolexp(f, o->key);
  223. X    putstring(f, o->fail_message);
  224. X    putstring(f, o->succ_message);
  225. X    putstring(f, o->ofail);
  226. X    putstring(f, o->osuccess);
  227. X    putref(f, o->owner);
  228. X    putref(f, o->pennies);
  229. X    putref(f, o->flags);
  230. X    putstring(f, o->password);
  231. X
  232. X    return 0;
  233. X}
  234. X
  235. Xdbref db_write(FILE *f)
  236. X{
  237. X    dbref i;
  238. X
  239. X    for(i = 0; i < db_top; i++) {
  240. X    fprintf(f, "#%d\n", i);
  241. X    db_write_object(f, i);
  242. X    }
  243. X    fputs("***END OF DUMP***\n", f);
  244. X    fflush(f);
  245. X    return(db_top);
  246. X}
  247. X
  248. Xdbref parse_dbref(const char *s)
  249. X{
  250. X    const char *p;
  251. X    long x;
  252. X
  253. X    x = atol(s);
  254. X    if(x > 0) {
  255. X    return x;
  256. X    } else if(x == 0) {
  257. X    /* check for 0 */
  258. X    for(p = s; *p; p++) {
  259. X        if(*p == '0') return 0;
  260. X        if(!isspace(*p)) break;
  261. X    }
  262. X    }
  263. X
  264. X    /* else x < 0 or s != 0 */
  265. X    return NOTHING;
  266. X}
  267. X        
  268. Xdbref getref(FILE *f)
  269. X{
  270. X    static char buf[DB_MSGLEN];
  271. X
  272. X    fgets(buf, sizeof(buf), f);
  273. X    return(atol(buf));
  274. X}
  275. X
  276. Xstatic const char *getstring_noalloc(FILE *f)
  277. X{
  278. X    static char buf[DB_MSGLEN];
  279. X    char *p;
  280. X
  281. X    fgets(buf, sizeof(buf), f);
  282. X    for(p = buf; *p; p++) {
  283. X    if(*p == '\n') {
  284. X        *p = '\0';
  285. X        break;
  286. X    }
  287. X    }
  288. X
  289. X    return buf;
  290. X}
  291. X
  292. X#define getstring(x) alloc_string(getstring_noalloc(x))
  293. X
  294. X#ifdef COMPRESS
  295. Xextern const char *compress(const char *);
  296. X#define getstring_compress(x) alloc_string(compress(getstring_noalloc(x)));
  297. X#else
  298. X#define getstring_compress(x) getstring(x)
  299. X#endif /* COMPRESS */
  300. X
  301. Xstatic struct boolexp *negate_boolexp(struct boolexp *b)
  302. X{
  303. X    struct boolexp *n;
  304. X
  305. X    /* Obscure fact: !NOTHING == NOTHING in old-format databases! */
  306. X    if(b == TRUE_BOOLEXP) return TRUE_BOOLEXP;
  307. X
  308. X    n = (struct boolexp *) malloc(sizeof(struct boolexp));
  309. X    n->type = BOOLEXP_NOT;
  310. X    n->sub1 = b;
  311. X
  312. X    return n;
  313. X}
  314. X
  315. Xstatic struct boolexp *getboolexp1(FILE *f)
  316. X{
  317. X    struct boolexp *b;
  318. X    int c;
  319. X
  320. X    c = getc(f);
  321. X    switch(c) {
  322. X      case '\n':
  323. X    ungetc(c, f);
  324. X    return TRUE_BOOLEXP;
  325. X    /* break; */
  326. X      case EOF:
  327. X    abort();        /* unexpected EOF in boolexp */
  328. X    break;
  329. X      case '(':
  330. X    b = (struct boolexp *) malloc(sizeof(struct boolexp));
  331. X    if((c = getc(f)) == '!') {
  332. X        b->type = BOOLEXP_NOT;
  333. X        b->sub1 = getboolexp1(f);
  334. X        if(getc(f) != ')') goto error;
  335. X        return b;
  336. X    } else {
  337. X        ungetc(c, f);
  338. X        b->sub1 = getboolexp1(f);
  339. X        switch(c = getc(f)) {
  340. X          case AND_TOKEN:
  341. X        b->type = BOOLEXP_AND;
  342. X        break;
  343. X          case OR_TOKEN:
  344. X        b->type = BOOLEXP_OR;
  345. X        break;
  346. X          default:
  347. X        goto error;
  348. X        /* break */
  349. X        }
  350. X        b->sub2 = getboolexp1(f);
  351. X        if(getc(f) != ')') goto error;
  352. X        return b;
  353. X    }
  354. X    /* break; */
  355. X      case '-':
  356. X    /* obsolete NOTHING key */
  357. X    /* eat it */
  358. X    while((c = getc(f)) != '\n') if(c == EOF) abort(); /* unexp EOF */
  359. X    ungetc(c, f);
  360. X    return TRUE_BOOLEXP;
  361. X    /* break */
  362. X      default:
  363. X    /* better be a dbref */
  364. X    ungetc(c, f);
  365. X    b = (struct boolexp *) malloc(sizeof(struct boolexp));
  366. X    b->type = BOOLEXP_CONST;
  367. X    b->thing = 0;
  368. X        
  369. X    /* NOTE possibly non-portable code */
  370. X    /* Will need to be changed if putref/getref change */
  371. X    while(isdigit(c = getc(f))) {
  372. X        b->thing = b->thing * 10 + c - '0';
  373. X    }
  374. X    ungetc(c, f);
  375. X    return b;
  376. X    }
  377. X
  378. X  error:
  379. X    abort();            /* bomb out */
  380. X    return TRUE_BOOLEXP;
  381. X}
  382. X
  383. Xstruct boolexp *getboolexp(FILE *f)
  384. X{
  385. X    struct boolexp *b;
  386. X
  387. X    b = getboolexp1(f);
  388. X    if(getc(f) != '\n') abort(); /* parse error, we lose */
  389. X    return b;
  390. X}
  391. X
  392. Xvoid free_boolexp(struct boolexp *b)
  393. X{
  394. X    if(b != TRUE_BOOLEXP) {
  395. X    switch(b->type) {
  396. X      case BOOLEXP_AND:
  397. X      case BOOLEXP_OR:
  398. X        free_boolexp(b->sub1);
  399. X        free_boolexp(b->sub2);
  400. X        free((void *) b);
  401. X        break;
  402. X      case BOOLEXP_NOT:
  403. X        free_boolexp(b->sub1);
  404. X        free((void *) b);
  405. X        break;
  406. X      case BOOLEXP_CONST:
  407. X        free((void *) b);
  408. X        break;
  409. X    }
  410. X    }
  411. X}
  412. X
  413. Xvoid db_free(void)
  414. X{
  415. X    dbref i;
  416. X    struct object *o;
  417. X
  418. X    if(db) {
  419. X    for(i = 0; i < db_top; i++) {
  420. X        o = &db[i];
  421. X        if(o->name) free((void *) o->name);
  422. X        if(o->description) free((void *) o->description);
  423. X        if(o->succ_message) free((void *) o->succ_message);
  424. X        if(o->fail_message) free((void *) o->fail_message);
  425. X        if(o->ofail) free((void *) o->ofail);
  426. X        if(o->osuccess) free((void *) o->osuccess);
  427. X        if(o->password) free((void *) o->password);
  428. X        if(o->key) free_boolexp(o->key);
  429. X    }
  430. X    free((void *) db);
  431. X    db = 0;
  432. X    db_top = 0;
  433. X    }
  434. X}
  435. X
  436. Xdbref db_read(FILE *f)
  437. X{
  438. X    dbref i;
  439. X    struct object *o;
  440. X    const char *end;
  441. X
  442. X#ifdef PLAYER_LIST
  443. X    clear_players();
  444. X#endif
  445. X    
  446. X    db_free();
  447. X    for(i = 0;; i++) {
  448. X    switch(getc(f)) {
  449. X      case '#':
  450. X        /* another entry, yawn */
  451. X        if(i != getref(f)) {
  452. X        /* we blew it */
  453. X        return -1;
  454. X        }
  455. X        /* make space */
  456. X        db_grow(i+1);
  457. X        
  458. X        /* read it in */
  459. X        o = db+i;
  460. X        o->name = getstring(f);
  461. X        o->description = getstring_compress(f);
  462. X        o->location = getref(f);
  463. X        o->contents = getref(f);
  464. X        o->exits = getref(f);
  465. X        o->next = getref(f);
  466. X        o->key = getboolexp(f);
  467. X        o->fail_message = getstring_compress(f);
  468. X        o->succ_message = getstring_compress(f);
  469. X        o->ofail = getstring_compress(f);
  470. X        o->osuccess = getstring_compress(f);
  471. X        o->owner = getref(f);
  472. X        o->pennies = getref(f);
  473. X        o->flags = getref(f);
  474. X        o->password = getstring(f);
  475. X        /* For downward compatibility with databases using the */
  476. X        /* obsolete ANTILOCK flag. */ 
  477. X        if(o->flags & ANTILOCK) {
  478. X          o->key = negate_boolexp(o->key);
  479. X          o->flags &= ~ANTILOCK;
  480. X        }
  481. X#ifdef PLAYER_LIST        
  482. X        if(Typeof(i) == TYPE_PLAYER) {
  483. X        add_player(i);
  484. X        }
  485. X#endif PLAYER_LIST        
  486. X        break;
  487. X      case '*':
  488. X        end = getstring(f);
  489. X        if(strcmp(end, "**END OF DUMP***")) {
  490. X        free((void *) end);
  491. X        return -1;
  492. X        } else {
  493. X        free((void *) end);
  494. X        return db_top;
  495. X        }
  496. X      default:
  497. X        return -1;
  498. X        /* break; */
  499. X    }
  500. X    }
  501. X}
  502. X        
  503. END_OF_FILE
  504. if test 9028 -ne `wc -c <'db.c'`; then
  505.     echo shar: \"'db.c'\" unpacked with wrong size!
  506. fi
  507. # end of 'db.c'
  508. fi
  509. if test -f 'game.c' -a "${1}" != "-c" ; then 
  510.   echo shar: Will not clobber existing file \"'game.c'\"
  511. else
  512. echo shar: Extracting \"'game.c'\" \(14143 characters\)
  513. sed "s/^X//" >'game.c' <<'END_OF_FILE'
  514. X#include "copyright.h"
  515. X
  516. X#include <stdio.h>
  517. X#include <ctype.h>
  518. X#include <signal.h>
  519. X#include <sys/wait.h>
  520. X#include <time.h>
  521. X#include <stdarg.h>
  522. X    
  523. X#include "db.h"
  524. X#include "config.h"
  525. X#include "interface.h"
  526. X#include "match.h"
  527. X#include "externs.h"
  528. X
  529. X/* declarations */
  530. Xstatic const char *dumpfile = 0;
  531. Xstatic int epoch = 0;
  532. Xstatic int alarm_triggered = 0;
  533. Xstatic int alarm_block = 0;
  534. X
  535. Xstatic void fork_and_dump(void);
  536. Xvoid dump_database(void);
  537. X
  538. Xvoid do_dump(dbref player)
  539. X{
  540. X    if(Wizard(player)) {
  541. X    alarm_triggered = 1;
  542. X    notify(player, "Dumping...");
  543. X    } else {
  544. X    notify(player, "Sorry, you are in a no dumping zone.");
  545. X    }
  546. X}
  547. X
  548. Xvoid do_shutdown(dbref player)
  549. X{
  550. X    if(Wizard(player)) {
  551. X    writelog("SHUTDOWN: by %s\n", unparse_object(player, player));
  552. X    fflush(stderr);
  553. X    shutdown_flag = 1;
  554. X    } else {
  555. X    notify(player, "Your delusions of grandeur have been duly noted.");
  556. X    }
  557. X}
  558. X    
  559. X/* should be void, but it's defined as int */
  560. Xstatic int alarm_handler(void)
  561. X{
  562. X    alarm_triggered = 1;
  563. X    if(!alarm_block) {
  564. X        fork_and_dump();
  565. X    }
  566. X    return 0;
  567. X}
  568. X
  569. Xstatic void dump_database_internal(void)
  570. X{
  571. X    char tmpfile[2048];
  572. X    FILE *f;
  573. X
  574. X    sprintf(tmpfile, "%s.#%d#", dumpfile, epoch - 1);
  575. X    unlink(tmpfile);        /* nuke our predecessor */
  576. X
  577. X    sprintf(tmpfile, "%s.#%d#", dumpfile, epoch);
  578. X
  579. X    if((f = fopen(tmpfile, "w")) != NULL) {
  580. X    db_write(f);
  581. X    fclose(f);
  582. X    if(rename(tmpfile, dumpfile) < 0) perror(tmpfile);
  583. X    } else {
  584. X    perror(tmpfile);
  585. X    }
  586. X}
  587. X
  588. Xvoid panic(const char *message)
  589. X{
  590. X    char panicfile[2048];
  591. X    FILE *f;
  592. X    int i;
  593. X
  594. X    writelog("PANIC: %s\n", message);
  595. X
  596. X    /* turn off signals */
  597. X    for(i = 0; i < NSIG; i++) {
  598. X    signal(i, SIG_IGN);
  599. X    }
  600. X
  601. X    /* shut down interface */
  602. X    emergency_shutdown();
  603. X
  604. X    /* dump panic file */
  605. X    sprintf(panicfile, "%s.PANIC", dumpfile);
  606. X    if((f = fopen(panicfile, "w")) == NULL) {
  607. X    perror("CANNOT OPEN PANIC FILE, YOU LOSE:");
  608. X#ifndef NODUMPCORE
  609. X    signal(SIGILL, SIG_DFL);
  610. X    abort();
  611. X#endif NODUMPCORE
  612. X    _exit(135);
  613. X    } else {
  614. X    writelog("DUMPING: %s\n", panicfile);
  615. X    db_write(f);
  616. X    fclose(f);
  617. X    writelog("DUMPING: %s (done)\n", panicfile);
  618. X#ifndef NODUMPCORE
  619. X    signal(SIGILL, SIG_DFL);
  620. X    abort();
  621. X#endif NODUMPCORE
  622. X    _exit(136);
  623. X    }
  624. X}
  625. X
  626. Xvoid writelog(const char *fmt, ...)
  627. X{
  628. X    va_list list;
  629. X    struct tm *tm;
  630. X    long t;
  631. X    char buffer[2048];
  632. X
  633. X    va_start(list, fmt);
  634. X    vsprintf(buffer, fmt, list);
  635. X    t = time(NULL);
  636. X    tm = localtime(&t);
  637. X    fprintf(stderr, "%d/%02d %02d:%02d:%02d %s",
  638. X        tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
  639. X        buffer);
  640. X    fflush(stderr);
  641. X    va_end(list);
  642. X}
  643. X
  644. Xvoid dump_database(void)
  645. X{
  646. X    epoch++;
  647. X
  648. X    writelog("DUMPING: %s.#%d#\n", dumpfile, epoch);
  649. X    dump_database_internal();
  650. X    writelog("DUMPING: %s.#%d# (done)\n", dumpfile, epoch);
  651. X}
  652. X
  653. Xstatic void fork_and_dump(void)
  654. X{
  655. X    int child;
  656. X
  657. X    epoch++;
  658. X
  659. X    writelog("CHECKPOINTING: %s.#%d#\n", dumpfile, epoch);
  660. X#ifdef USE_VFORK
  661. X    child = vfork();
  662. X#else /* USE_VFORK */
  663. X    child = fork();
  664. X#endif /* USE_VFORK */
  665. X    if(child == 0) {
  666. X    /* in the child */
  667. X    close(0);        /* get that file descriptor back */
  668. X    dump_database_internal();
  669. X    _exit(0);        /* !!! */
  670. X    } else if(child < 0) {
  671. X    perror("fork_and_dump: fork()");
  672. X    }
  673. X    
  674. X    /* in the parent */
  675. X    /* reset alarm */
  676. X    alarm_triggered = 0;
  677. X    alarm(DUMP_INTERVAL);
  678. X}
  679. X
  680. Xstatic int reaper(void)
  681. X{
  682. X    union wait stat;
  683. X
  684. X    while(wait3(&stat, WNOHANG, 0) > 0);
  685. X    return 0;
  686. X}
  687. X
  688. Xint init_game(const char *infile, const char *outfile)
  689. X{
  690. X   FILE *f;
  691. X
  692. X   if((f = fopen(infile, "r")) == NULL) return -1;
  693. X   
  694. X   /* ok, read it in */
  695. X   writelog("LOADING: %s\n", infile);
  696. X   if(db_read(f) < 0) return -1;
  697. X   writelog("LOADING: %s (done)\n", infile);
  698. X
  699. X   /* everything ok */
  700. X   fclose(f);
  701. X
  702. X   /* initialize random number generator */
  703. X   srandom(getpid());
  704. X
  705. X   /* set up dumper */
  706. X   if(dumpfile) free((void *) dumpfile);
  707. X   dumpfile = alloc_string(outfile);
  708. X   signal(SIGALRM, (void (*)) alarm_handler);
  709. X   signal(SIGHUP, (void (*)) alarm_handler);
  710. X   signal(SIGCHLD, (void (*)) reaper);
  711. X   alarm_triggered = 0;
  712. X   alarm(DUMP_INTERVAL);
  713. X   
  714. X   return 0;
  715. X}
  716. X
  717. X/* use this only in process_command */
  718. X#define Matched(string) { if(!string_prefix((string), command)) goto bad; }
  719. X
  720. Xvoid process_command(dbref player, char *command)
  721. X{
  722. X    char *arg1;
  723. X    char *arg2;
  724. X    char *q;            /* utility */
  725. X    char *p;            /* utility */
  726. X
  727. X    char *index(char *, char);
  728. X
  729. X    if(command == 0) abort();
  730. X
  731. X    /* robustify player */
  732. X    if(player < 0 || player >= db_top || Typeof(player) != TYPE_PLAYER) {
  733. X    writelog("process_command: bad player %d\n", player);
  734. X    return;
  735. X    }
  736. X
  737. X#ifdef LOG_COMMANDS
  738. X    writelog("COMMAND from %s(%d) in %s(%d): %s\n",
  739. X        db[player].name, player,
  740. X        db[db[player].location].name, db[player].location,
  741. X        command);
  742. X#endif /* LOG_COMMANDS */
  743. X
  744. X    /* eat leading whitespace */
  745. X    while(*command && isspace(*command)) command++;
  746. X
  747. X    /* eat extra white space */
  748. X    q = p = command;
  749. X    while(*p) {
  750. X    /* scan over word */
  751. X    while(*p && !isspace(*p)) *q++ = *p++;
  752. X    /* smash spaces */
  753. X    while(*p && isspace(*++p));
  754. X    if(*p) *q++ = ' '; /* add a space to separate next word */
  755. X    }
  756. X    /* terminate */
  757. X    *q = '\0';
  758. X
  759. X    /* block dump to prevent db inconsistencies from showing up */
  760. X    alarm_block = 1;
  761. X
  762. X    /* check for single-character commands */
  763. X    if(*command == SAY_TOKEN) {
  764. X    do_say(player, command+1, NULL);
  765. X    } else if(*command == POSE_TOKEN) {
  766. X    do_pose(player, command+1, NULL);
  767. X    } else if(can_move(player, command)) {
  768. X    /* command is an exact match for an exit */
  769. X    do_move(player, command);
  770. X    } else {
  771. X    /* parse arguments */
  772. X
  773. X    /* find arg1 */
  774. X    /* move over command word */
  775. X    for(arg1 = command; *arg1 && !isspace(*arg1); arg1++);
  776. X    /* truncate command */
  777. X    if(*arg1) *arg1++ = '\0';
  778. X
  779. X    /* move over spaces */
  780. X    while(*arg1 && isspace(*arg1)) arg1++;
  781. X
  782. X    /* find end of arg1, start of arg2 */
  783. X    for(arg2 = arg1; *arg2 && *arg2 != ARG_DELIMITER; arg2++);
  784. X
  785. X    /* truncate arg1 */
  786. X    for(p = arg2 - 1; p >= arg1 && isspace(*p); p--) *p = '\0';
  787. X
  788. X    /* go past delimiter if present */
  789. X    if(*arg2) *arg2++ = '\0';
  790. X    while(*arg2 && isspace(*arg2)) arg2++;
  791. X
  792. X    switch(command[0]) {
  793. X      case '@':
  794. X        switch(command[1]) {
  795. X          case 'b':
  796. X          case 'B':
  797. X              switch (command[2]) {
  798. X          case 'o':
  799. X          case 'O':
  800. X            switch (command[3]) {
  801. X              case 'o':
  802. X              case 'O':    Matched("@boot");
  803. X                do_boot(player, arg1);
  804. X                      break;
  805. X              case 'b':
  806. X              case 'B':    if(string_compare(command, "@bobble")) goto bad;
  807. X                do_bobble(player, arg1, arg2);
  808. X                break;
  809. X             default:    goto bad;
  810. X            }
  811. X            break;
  812. X          default: goto bad;
  813. X        }
  814. X        break;
  815. X          case 'c':
  816. X          case 'C':
  817. X        /* chown, create */
  818. X        switch(command[2]) {
  819. X          case 'h':
  820. X          case 'H':
  821. X            Matched("@chown");
  822. X            do_chown(player, arg1, arg2);
  823. X            break;
  824. X#ifdef RECYCLE
  825. X          case 'o':
  826. X          case 'O':
  827. X            Matched("@count");
  828. X            do_count(player, arg1);
  829. X            break;
  830. X#endif RECYCLE
  831. X          case 'r':
  832. X          case 'R':
  833. X            Matched("@create");
  834. X            do_create(player, arg1, atol(arg2));
  835. X            break;
  836. X          default:
  837. X            goto bad;
  838. X        }
  839. X        break;
  840. X          case 'd':
  841. X          case 'D':
  842. X        /* describe, dig, or dump */
  843. X        switch(command[2]) {
  844. X          case 'e':
  845. X          case 'E':
  846. X            Matched("@describe");
  847. X            do_describe(player, arg1, arg2);
  848. X            break;
  849. X          case 'i':
  850. X          case 'I':
  851. X            Matched("@dig");
  852. X            do_dig(player, arg1);
  853. X            break;
  854. X          case 'u':
  855. X          case 'U':
  856. X            Matched("@dump");
  857. X            do_dump(player);
  858. X            break;
  859. X          default:
  860. X            goto bad;
  861. X        }
  862. X        break;
  863. X          case 'f':
  864. X        /* fail, find, or force */
  865. X        switch(command[2]) {
  866. X          case 'a':
  867. X          case 'A':
  868. X            Matched("@fail");
  869. X            do_fail(player, arg1, arg2);
  870. X            break;
  871. X          case 'i':
  872. X          case 'I':
  873. X            Matched("@find");
  874. X            do_find(player, arg1);
  875. X            break;
  876. X          case 'o':
  877. X          case 'O':
  878. X            Matched("@force");
  879. X            do_force(player, arg1, arg2);
  880. X            break;
  881. X          default:
  882. X            goto bad;
  883. X        }
  884. X        break;
  885. X          case 'l':
  886. X          case 'L':
  887. X        /* lock or link */
  888. X        switch(command[2]) {
  889. X          case 'i':
  890. X          case 'I':
  891. X            Matched("@link");
  892. X            do_link(player, arg1, arg2);
  893. X            break;
  894. X          case 'o':
  895. X          case 'O':
  896. X            Matched("@lock");
  897. X            do_lock(player, arg1, arg2);
  898. X            break;
  899. X          default:
  900. X            goto bad;
  901. X        }
  902. X        break;
  903. X          case 'm':
  904. X          case 'M':
  905. X              Matched("@mass_teleport");
  906. X        do_mass_teleport(player, arg1);
  907. X              break;
  908. X          case 'n':
  909. X          case 'N':
  910. X        /* @name or @newpassword */
  911. X        switch(command[2]) {
  912. X          case 'a':
  913. X          case 'A':
  914. X            Matched("@name");
  915. X            do_name(player, arg1, arg2);
  916. X            break;
  917. X          case 'e':
  918. X            if(strcmp(command, "@newpassword")) goto bad;
  919. X            do_newpassword(player, arg1, arg2);
  920. X            break;
  921. X          default:
  922. X            goto bad;
  923. X        }
  924. X        break;
  925. X          case 'o':
  926. X          case 'O':
  927. X        switch(command[2]) {
  928. X          case 'f':
  929. X          case 'F':
  930. X            Matched("@ofail");
  931. X            do_ofail(player, arg1, arg2);
  932. X            break;
  933. X          case 'p':
  934. X          case 'P':
  935. X            Matched("@open");
  936. X            do_open(player, arg1, arg2);
  937. X            break;
  938. X          case 's':
  939. X          case 'S':
  940. X            Matched("@osuccess");
  941. X            do_osuccess(player, arg1, arg2);
  942. X            break;
  943. X          case 'w':
  944. X          case 'W':
  945. X            Matched("@owned");
  946. X            do_owned(player, arg1);
  947. X            break;
  948. X          default:
  949. X            goto bad;
  950. X        }
  951. X        break;
  952. X          case 'p':
  953. X          case 'P':
  954. X         switch(command[2]) {
  955. X           case 'a':
  956. X           case 'A':
  957. X             Matched("@password");
  958. X             do_password(player, arg1, arg2);
  959. X             break;
  960. X#ifdef REGISTRATION            
  961. X           case 'c':
  962. X           case 'C':
  963. X             Matched("@pcreate");
  964. X             do_pcreate(player, arg1, arg2);
  965. X             break;
  966. X#endif REGISTRATION
  967. X              default: goto bad;
  968. X         }
  969. X        break;
  970. X#ifdef RECYCLE
  971. X          case 'r':
  972. X          case 'R':
  973. X              /* Recycle */
  974. X        Matched("@recycle");
  975. X        do_recycle(player, arg1);
  976. X        break;
  977. X#endif RECYCLE
  978. X          case 's':
  979. X          case 'S':
  980. X        /* set, shutdown, success */
  981. X        switch(command[2]) {
  982. X          case 'e':
  983. X          case 'E':
  984. X            Matched("@set");
  985. X            do_set(player, arg1, arg2);
  986. X            break;
  987. X          case 'h':
  988. X            if(strcmp(command, "@shutdown")) goto bad;
  989. X            do_shutdown(player);
  990. X            break;
  991. X          case 't':
  992. X          case 'T':
  993. X            Matched("@stats");
  994. X            do_stats(player, arg1);
  995. X            break;
  996. X          case 'u':
  997. X          case 'U':
  998. X            Matched("@success");
  999. X            do_success(player, arg1, arg2);
  1000. X            break;
  1001. X          default:
  1002. X            goto bad;
  1003. X        }
  1004. X        break;
  1005. X          case 't':
  1006. X          case 'T':
  1007. X        switch(command[2]) {
  1008. X          case 'e':
  1009. X          case 'E':
  1010. X            Matched("@teleport");
  1011. X            do_teleport(player, arg1, arg2);
  1012. X            break;
  1013. X          case 'o':
  1014. X          case 'O':
  1015. X            if(string_compare(command, "@toad")) goto bad;
  1016. X            do_bobble(player, arg1, arg2);
  1017. X            break;
  1018. X          default:
  1019. X            goto bad;
  1020. X        }
  1021. X        break;
  1022. X          case 'u':
  1023. X          case 'U':
  1024. X        if(string_prefix(command, "@unli")) {
  1025. X            Matched("@unlink");
  1026. X            do_unlink(player, arg1);
  1027. X        } else if(string_prefix(command, "@unlo")) {
  1028. X            Matched("@unlock");
  1029. X            do_unlock(player, arg1);
  1030. X        } else if(string_prefix(command, "@unb")) {
  1031. X            Matched("@unbobble");
  1032. X            do_unbobble(player, arg1, arg2);
  1033. X        } else if(string_prefix(command, "@unt")) {
  1034. X            Matched("@untoad");
  1035. X            do_unbobble(player, arg1, arg2);
  1036. X        } else {
  1037. X            goto bad;
  1038. X        }
  1039. X        break;
  1040. X          case 'w':
  1041. X        if(strcmp(command, "@wall")) goto bad;
  1042. X        do_wall(player, arg1, arg2);
  1043. X        break;
  1044. X          default:
  1045. X        goto bad;
  1046. X        }
  1047. X        break;
  1048. X      case 'd':
  1049. X      case 'D':
  1050. X        Matched("drop");
  1051. X        do_drop(player, arg1);
  1052. X        break;
  1053. X      case 'e':
  1054. X      case 'E':
  1055. X        if (command[1] == 'x' || command[1] == 'X') {
  1056. X        Matched("examine");
  1057. X        do_examine(player, arg1);
  1058. X        break;
  1059. X        } else {
  1060. X        goto bad;
  1061. X        }
  1062. X      case 'g':
  1063. X      case 'G':
  1064. X        /* get, give, go, or gripe */
  1065. X        switch(command[1]) {
  1066. X          case 'e':
  1067. X          case 'E':
  1068. X        Matched("get");
  1069. X        do_get(player, arg1);
  1070. X        break;
  1071. X          case 'i':
  1072. X          case 'I':
  1073. X        Matched("give");
  1074. X        do_give(player, arg1, atol(arg2));
  1075. X        break;
  1076. X          case 'o':
  1077. X          case 'O':
  1078. X        Matched("goto");
  1079. X        do_move(player, arg1);
  1080. X        break;
  1081. X          case 'r':
  1082. X          case 'R':
  1083. X        Matched("gripe");
  1084. X        do_gripe(player, arg1, arg2);
  1085. X        break;
  1086. X          default:
  1087. X        goto bad;
  1088. X        }
  1089. X        break;
  1090. X      case 'h':
  1091. X      case 'H':
  1092. X        Matched("help");
  1093. X        do_help(player);
  1094. X        break;
  1095. X      case 'i':
  1096. X      case 'I':
  1097. X        Matched("inventory");
  1098. X        do_inventory(player);
  1099. X        break;
  1100. X      case 'k':
  1101. X      case 'K':
  1102. X        Matched("kill");
  1103. X        do_kill(player, arg1, atol(arg2));
  1104. X        break;
  1105. X      case 'l':
  1106. X      case 'L':
  1107. X        Matched("look");
  1108. X        do_look_at(player, arg1);
  1109. X        break;
  1110. X      case 'm':
  1111. X      case 'M':
  1112. X        Matched("move");
  1113. X        do_move(player, arg1);
  1114. X        break;
  1115. X      case 'n':
  1116. X      case 'N':
  1117. X        /* news */
  1118. X        if(string_compare(command, "news")) goto bad;
  1119. X        do_news(player);
  1120. X        break;
  1121. X      case 'p':
  1122. X      case 'P':
  1123. X        Matched("page");
  1124. X        do_page(player, arg1, arg2);
  1125. X        break;
  1126. X      case 'r':
  1127. X      case 'R':
  1128. X        switch(command[1]) {
  1129. X          case 'e':
  1130. X          case 'E':
  1131. X        Matched("read"); /* undocumented alias for look at */
  1132. X        do_look_at(player, arg1);
  1133. X        break;
  1134. X          case 'o':
  1135. X          case 'O':
  1136. X        Matched("rob");
  1137. X        do_rob(player, arg1);
  1138. X        break;
  1139. X          default:
  1140. X        goto bad;
  1141. X        }
  1142. X        break;
  1143. X      case 's':
  1144. X      case 'S':
  1145. X        /* say, "score" */
  1146. X        switch(command[1]) {
  1147. X          case 'a':
  1148. X          case 'A':
  1149. X        Matched("say");
  1150. X        do_say(player, arg1, arg2);
  1151. X        break;
  1152. X          case 'c':
  1153. X          case 'C':
  1154. X        Matched("score");
  1155. X        do_score(player);
  1156. X        break;
  1157. X          default:
  1158. X        goto bad;
  1159. X        }
  1160. X        break;
  1161. X      case 't':
  1162. X      case 'T':
  1163. X        switch(command[1]) {
  1164. X          case 'a':
  1165. X          case 'A':
  1166. X        Matched("take");
  1167. X        do_get(player, arg1);
  1168. X        break;
  1169. X          case 'h':
  1170. X          case 'H':
  1171. X        Matched("throw");
  1172. X        do_drop(player, arg1);
  1173. X        break;
  1174. X          default:
  1175. X        goto bad;
  1176. X        }
  1177. X        break;
  1178. X      case 'w':
  1179. X      case 'W':
  1180. X        Matched("whisper");
  1181. X        do_whisper(player, arg1, arg2);
  1182. X        break;
  1183. X      default:
  1184. X      bad:
  1185. X        notify(player, "Huh?  (Type \"help\" for help.)");
  1186. X#ifdef LOG_FAILED_COMMANDS
  1187. X        if(!controls(player, db[player].location)) {
  1188. X        writelog("HUH from %s(%d) in %s(%d)[%s]: %s %s\n",
  1189. X            db[player].name, player,
  1190. X            db[db[player].location].name,
  1191. X            db[player].location,
  1192. X            db[db[db[player].location].owner].name,
  1193. X            command,
  1194. X            reconstruct_message(arg1, arg2));
  1195. X        }
  1196. X#endif /* LOG_FAILED_COMMANDS */
  1197. X        break;
  1198. X    }
  1199. X    }
  1200. X
  1201. X    /* unblock alarms */
  1202. X    alarm_block = 0;
  1203. X    if(alarm_triggered) {
  1204. X    fork_and_dump();
  1205. X    }
  1206. X}
  1207. X
  1208. X#undef Matched
  1209. END_OF_FILE
  1210. if test 14143 -ne `wc -c <'game.c'`; then
  1211.     echo shar: \"'game.c'\" unpacked with wrong size!
  1212. fi
  1213. # end of 'game.c'
  1214. fi
  1215. if test -f 'restart-cmu' -a "${1}" != "-c" ; then 
  1216.   echo shar: Will not clobber existing file \"'restart-cmu'\"
  1217. else
  1218. echo shar: Extracting \"'restart-cmu'\" \(576 characters\)
  1219. sed "s/^X//" >'restart-cmu' <<'END_OF_FILE'
  1220. X#!/bin/csh -f
  1221. X#
  1222. X# This script assumes you have the following structure:
  1223. X#
  1224. X#    $HOME/bin    executable MUD programs
  1225. X#    $HOME/lib    database files, daily logs
  1226. X#    $HOME/src    source code for netmud
  1227. X#
  1228. X
  1229. Xcd /usr/tinymud/lib
  1230. Xmv tinymud.db tinymud.db.old
  1231. Xif(-r tinymud.db.new) then
  1232. X    mv tinymud.db.new tinymud.db
  1233. Xelse
  1234. X    cp tinymud.db.old tinymud.db
  1235. Xendif
  1236. X
  1237. X# Use netmud instead of netmud.conc if you don't want the port concentrator
  1238. Xcp ../bin/netmud.conc netmud.exe
  1239. Xcp ../bin/concentrate concentrate
  1240. X
  1241. Xecho RESTARTED AT `date` >> tinymud.log
  1242. X./netmud.exe tinymud.db tinymud.db.new >>& tinymud.log &
  1243. END_OF_FILE
  1244. if test 576 -ne `wc -c <'restart-cmu'`; then
  1245.     echo shar: \"'restart-cmu'\" unpacked with wrong size!
  1246. fi
  1247. chmod +x 'restart-cmu'
  1248. # end of 'restart-cmu'
  1249. fi
  1250. if test -f 'tinymud.tex' -a "${1}" != "-c" ; then 
  1251.   echo shar: Will not clobber existing file \"'tinymud.tex'\"
  1252. else
  1253. echo shar: Extracting \"'tinymud.tex'\" \(28102 characters\)
  1254. sed "s/^X//" >'tinymud.tex' <<'END_OF_FILE'
  1255. X\documentstyle[11pt,titlepage,makeidx,ragright]{article}
  1256. X
  1257. X\newcommand{\bs}{\char '134}    % backslash character for \tt font
  1258. X\newcommand{\ub}{\char '137}    % underbar character for \tt font
  1259. X\newcommand{\ua}{\char '136}    % up arrow character for \tt font
  1260. X\newcommand{\qt}{\char '175}    % quotes character for \tt font
  1261. X\newcommand{\tl}{\char '176}    % tilde character for \tt font
  1262. X\newcommand{\sh}{\char '043}    % sharp character for \tt font
  1263. X
  1264. X\newcommand{\tinymud}{{\small Tiny}{MUD}}
  1265. X\newcommand{\type}[1]{{\tt #1\/}}
  1266. X
  1267. X\newenvironment{simple}{\begin{list}%
  1268. X{\relax}%
  1269. X{\setlength{\labelwidth}{0pt}%
  1270. X \setlength{\labelsep}{0pt}%
  1271. X \setlength{\leftmargin}{0pt}%
  1272. X \setlength{\listparindent}{0pt}}}%
  1273. X{\end{list}}
  1274. X
  1275. X%\newenvironment{simple}{\begin{trivlist}}{\end{trivlist}}
  1276. X
  1277. X%\newlength{\boxwidth}
  1278. X%\setlength{\boxwidth}{\textwidth}
  1279. X%\addtolength{\boxwidth}{-7pt}
  1280. X
  1281. X\newlength{\rulewidth}
  1282. X\setlength{\rulewidth}{\textwidth}
  1283. X%\divide\rulewidth by 3
  1284. X
  1285. X\newcommand{\dorule}{\begin{center}
  1286. X\rule{\rulewidth}{1pt}
  1287. X\end{center}}
  1288. X
  1289. X\makeindex
  1290. X
  1291. X\title{{\bf A brief guide to {\large\bf Tiny}MUD}}
  1292. X
  1293. X\author{Jennifer Stone (aka Chrysalis) \\
  1294. X{\tt jennifer@uokmax.ecn.uoknor.edu}
  1295. X\and
  1296. XRusty C. Wright \\
  1297. X{\tt rusty@garnet.berkeley.edu}}
  1298. X
  1299. X\begin{document}
  1300. X
  1301. X% uncomment the commented lines if you want a more formal document
  1302. X% with a separate title page and table of contents.
  1303. X
  1304. X\ragright
  1305. X
  1306. X\pagenumbering{roman}
  1307. X
  1308. X\maketitle
  1309. X
  1310. X\tableofcontents
  1311. X\clearpage
  1312. X
  1313. X\pagenumbering{arabic}
  1314. X
  1315. XMuch of this is from the {\tinymud} source code and the {\tt small.db}
  1316. Xexample.
  1317. X
  1318. X\section{Ordinary commands}
  1319. X\label{sec:ordinary-commands}
  1320. X
  1321. X\begin{simple}
  1322. X
  1323. X\item[]
  1324. X\begin{flushleft}
  1325. X{\tt drop} $<${\em object\/}$>$ \\
  1326. X{\tt throw} $<${\em object\/}$>$
  1327. X\index{drop@\type{drop}}
  1328. X\index{throw@\type{throw}}
  1329. X\end{flushleft}
  1330. XDrops the specified object.  $<${\em object\/}$>$ can be either a
  1331. Xthing or exit.
  1332. X
  1333. X\dorule
  1334. X
  1335. X\item[]
  1336. X\begin{flushleft}
  1337. X{\tt examine} $<${\em name\/}$>$ \\
  1338. X{\tt examine} {\tt \#}$<${\em number\/}$>$
  1339. X\index{examine@\type{examine}}
  1340. X\end{flushleft}
  1341. XPrints a detailed description of object specified by $<${\em
  1342. Xname\/}$>$ or by $<${\em number\/}$>$ giving name, description, owner,
  1343. Xkeys, pennies, failure message, success message, others failure
  1344. Xmessage, others success message, and exits.  The location will also be
  1345. Xdisplayed if you control the object's location (that is, if it's not
  1346. Xbeing carried by someone else or in a room you don't control).
  1347. X
  1348. X\dorule
  1349. X
  1350. X\item[]
  1351. X\begin{flushleft}
  1352. X{\tt get} $<${\em object\/}$>$ \\
  1353. X{\tt take} $<${\em object\/}$>$
  1354. X\index{get@\type{get}}
  1355. X\index{take@\type{take}}
  1356. X\end{flushleft}
  1357. XGets the specified object.  $<${\em object\/}$>$ can be either a thing
  1358. Xor exit.
  1359. X
  1360. X\dorule
  1361. X
  1362. X\item[]
  1363. X\begin{flushleft}
  1364. X{\tt give} $<${\em player\/}$>$ \verb|=| $<${\em amount\/}$>$
  1365. X\index{give@\type{give}}
  1366. X\end{flushleft}
  1367. XGives $<${\em player\/}$>$ the specified number of pennies.
  1368. X
  1369. X\dorule
  1370. X
  1371. X\item[]
  1372. X\begin{flushleft}
  1373. X{\tt go} $<${\em direction\/}$>$ \\
  1374. X{\tt go home} \\
  1375. X{\tt move} $<${\em direction\/}$>$ \\
  1376. X{\tt move home}
  1377. X\index{go@\type{go}}
  1378. X\index{move@\type{move}}
  1379. X\index{home@\type{home}}
  1380. X\end{flushleft}
  1381. X
  1382. XMoves in the specified direction.  {\tt go home} is a special command
  1383. Xthat returns you to your home (initially Limbo).  If the direction is
  1384. Xfully specified, the {\tt go} may be omitted.
  1385. X
  1386. X\dorule
  1387. X
  1388. X\item[]
  1389. X\begin{flushleft}
  1390. X{\tt gripe} $<${\em message\/}$>$
  1391. X\index{gripe@\type{gripe}}
  1392. X\end{flushleft}
  1393. XSends $<${\em message\/}$>$ to the system maintainer.
  1394. X
  1395. X\dorule
  1396. X
  1397. X\item[]
  1398. X\begin{flushleft}
  1399. X{\tt help}
  1400. X\index{help@\type{help}}
  1401. X\end{flushleft}
  1402. XPrints a short help message.
  1403. X
  1404. X\dorule
  1405. X
  1406. X\item[]
  1407. X\begin{flushleft}
  1408. X{\tt inventory}
  1409. X\index{inventory@\type{inventory}}
  1410. X\end{flushleft}
  1411. XLists what you are carrying.
  1412. X
  1413. X\dorule
  1414. X
  1415. X\item[]
  1416. X\begin{flushleft}
  1417. X{\tt kill} $<${\em player\/}$>$ $[$ \verb|=| $<${\em cost\/}$>$ $]$
  1418. X\index{kill@\type{kill}}
  1419. X\end{flushleft}
  1420. XKills the specified player.  Killing costs either $<${\em cost\/}$>$
  1421. Xpennies or 10 pennies, whichever is greater.  The probability of
  1422. Xsuccess is proportional to the cost.
  1423. X
  1424. X\dorule
  1425. X
  1426. X\item[]
  1427. X\begin{flushleft}
  1428. X{\tt look} $<${\em object\/}$>$ \\
  1429. X{\tt read} $<${\em object\/}$>$
  1430. X\index{look@\type{look}}
  1431. X\index{read@\type{read}}
  1432. X\end{flushleft}
  1433. X$<${\em object\/}$>$ can be a room, thing, player, or direction.  Prints
  1434. Xa description of $<${\em object\/}$>$.
  1435. X
  1436. X\dorule
  1437. X
  1438. X\item[]
  1439. X\begin{flushleft}
  1440. X{\tt page} $<${\em player\/}$>$
  1441. X\index{page@\type{page}}
  1442. X\end{flushleft}
  1443. XUsed to inform an active player that you are looking for them.  The
  1444. Xtargeted player will get a message telling them your name and
  1445. Xlocation.
  1446. X
  1447. X\dorule
  1448. X
  1449. X\item[]
  1450. X\begin{flushleft}
  1451. X{\tt rob} $<${\em player\/}$>$
  1452. X\index{rob@\type{rob}}
  1453. X\end{flushleft}
  1454. XAttempt to steal a penny from $<${\em player\/}$>$.
  1455. X
  1456. X\dorule
  1457. X
  1458. X\item[]
  1459. X\begin{flushleft}
  1460. X{\tt say} $<${\em message\/}$>$ \\
  1461. X\verb|"|$<${\em message\/}$>$ \\
  1462. X\verb|:|$<${\em message\/}$>$
  1463. X\index{say@\type{say}}
  1464. X\index{""@\type{""}}
  1465. X\index{:@\type{:}}
  1466. X\end{flushleft}
  1467. XThe first two forms display the $<${\em message\/}$>$ with the
  1468. Xnotification that you said it.  For example, if your player's name is
  1469. XBetty the other players in the same room will see
  1470. X\begin{flushleft}
  1471. X{\tt Betty says} ``$<${\em message\/}$>$''
  1472. X\end{flushleft}
  1473. XThe third form {\sl poses} the message, preceded by your name, with no
  1474. Xquotes, as in
  1475. X\begin{flushleft}
  1476. X{\tt Betty} $<${\em message\/}$>$
  1477. X\end{flushleft}
  1478. XFor both the second and third forms, do not put a space after
  1479. Xthe double quotes or colon as it will be included in the message.
  1480. X
  1481. X\dorule
  1482. X
  1483. X\item[]
  1484. X\begin{flushleft}
  1485. X{\tt score}
  1486. X\index{score@\type{score}}
  1487. X\end{flushleft}
  1488. XPrints how many pennies you have.
  1489. X
  1490. X\dorule
  1491. X
  1492. X\item[]
  1493. X\begin{flushleft}
  1494. X{\tt whisper} $<${\em player\/}$>$ \verb|=| $<${\em message\/}$>$
  1495. X\index{whisper@\type{whisper}}
  1496. X\end{flushleft}
  1497. X$<${\em player\/}$>$ is presented with $<${\em message\/}$>$ saying
  1498. Xthat you whispered it.  The other players only see the message
  1499. X\begin{flushleft}
  1500. X{\tt Betty whispers something to} $<${\em player\/}$>$.
  1501. X\end{flushleft}
  1502. X
  1503. X\end{simple}
  1504. X
  1505. X\section{Commands for modifying the dungeon}
  1506. X\label{sec:commands-for-modifying-the-dungeon}
  1507. X
  1508. X\begin{simple}
  1509. X
  1510. X\item[]
  1511. X\begin{flushleft}
  1512. X{\tt @create\/} $<${\em name\/}$>$ $[$ \verb|=| $<${\em cost\/}$>$ $]$
  1513. X\index{create@\type{"@create}}
  1514. X\end{flushleft}
  1515. XCreates a thing with the specified name.  Creation costs either
  1516. X$<${\em cost\/}$>$ pennies or 10 pennies, whichever is greater.  The
  1517. Xvalue of a thing is proportional to its cost.
  1518. X
  1519. X\dorule
  1520. X
  1521. X\item[]
  1522. X\begin{flushleft}
  1523. X{\tt @describe} $<${\em object\/}$>$ \verb|=| $<${\em description\/}$>$
  1524. X\index{describe@\type{"@describe}}
  1525. X\end{flushleft}
  1526. X$<${\em object\/}$>$ can be a room, thing, player, or direction.  Sets
  1527. Xthe description a player sees when they use the command {\tt look}
  1528. X$<${\em object\/}$>$.  If $<${\em object\/}$>$ is {\tt
  1529. Xhere}\index{here@\type{here}} it sets the description for the current
  1530. Xroom that is displayed when the room is entered.  If $<${\em
  1531. Xobject\/}$>$ is {\tt me}\index{me@\type{me}} it sets the description for
  1532. Xyour character.
  1533. X
  1534. X\dorule
  1535. X
  1536. X\item[]
  1537. X\begin{flushleft}
  1538. X{\tt @dig} $<${\em name\/}$>$
  1539. X\index{dig@\type{"@dig}}
  1540. X\end{flushleft}
  1541. XCreates a new room with the specified name, and prints the room's
  1542. Xnumber.
  1543. X
  1544. X\dorule
  1545. X
  1546. X\item[]
  1547. X\begin{flushleft}
  1548. X{\tt @fail} $<${\em object\/}$>$ $[$ \verb|=| $<${\em message\/}$>$
  1549. X$]$
  1550. X\index{fail@\type{"@fail}}
  1551. X\end{flushleft}
  1552. XWithout a message argument, clears the failure message on $<${\em
  1553. Xobject\/}$>$, otherwise sets it.  The failure message is printed when
  1554. Xa player unsuccessfully attempts to use the object.
  1555. X
  1556. X\dorule
  1557. X
  1558. X\item[]
  1559. X\begin{flushleft}
  1560. X{\tt @find} $<${\em name\/}$>$
  1561. X\index{find@\type{"@find}}
  1562. X\end{flushleft}
  1563. XPrints the name and object number of every room, thing, or player that
  1564. Xyou control whose name matches $<${\em name\/}$>$.  Because the {\tt
  1565. X@find} command is computationally expensive, there is a small charge
  1566. Xfor using it.
  1567. X
  1568. X\dorule
  1569. X
  1570. X\item[]
  1571. X\begin{flushleft}
  1572. X{\tt @link} $<${\em direction\/}$>$ \verb|=| $<${\em room number\/}$>$ \\
  1573. X{\tt @link} $<${\em thing\/}$>$ \verb|=| $<${\em room number\/}$>$ \\
  1574. X{\tt @link} $<${\em room\/}$>$ \verb|=| $<${\em room number\/}$>$
  1575. X\index{link@\type{"@link}}
  1576. X\end{flushleft}
  1577. XIn the first form links the exit specified by $<${\em direction\/}$>$
  1578. Xto the room specified by $<${\em room number\/}$>$.  The exit must be
  1579. Xunlinked, and you must own the target room if its
  1580. X\verb|link_ok|\index{linkok@\verb,link_ok,} attribute is not set.  If
  1581. Xyou don't already own the exit its ownership is transferred to you.
  1582. XThe second form sets the home for $<${\em thing\/}$>$\index{home}.  If
  1583. X$<${\em thing\/}$>$ is {\tt me}\index{me@\type{me}} it sets your home.
  1584. XThe third form sets the dropto; see section~\ref{sec:droptos} for an
  1585. Xexplanation of dropto's.
  1586. X
  1587. X\dorule
  1588. X
  1589. X\item[]
  1590. X\begin{flushleft}
  1591. X{\tt @lock} $<${\em object\/}$>$ \verb|=| $<${\em key\/}$>$
  1592. X\index{lock@\type{"@lock}}
  1593. X\end{flushleft}
  1594. XSets a key (another object) for an object.  If $<${\em key\/}$>$
  1595. Xstarts with \verb|*| then it must be a player's name.  $<${\em
  1596. Xkey\/}$>$ can contain the Boolean operators \verb|!| (not or
  1597. Xnegation), \verb|&| (and), and \verb:|: (or), and use parentheses for
  1598. Xgrouping.
  1599. X
  1600. XIn order to use $<${\em object\/}$>$ you must satisfy the requirements
  1601. Xof $<${\em key\/}$>$.  In the simplest case you must simply have
  1602. X$<${\em key\/}$>$.  If $<${\em key\/}$>$ is preceded by \verb|!| then
  1603. Xyou must not have $<${\em key\/}$>$ in order to use $<${\em
  1604. Xobject\/}$>$.  See section~\ref{sec:lock-key-boolean-examples} for
  1605. Xmore complicated examples.
  1606. X
  1607. X\dorule
  1608. X
  1609. X\item[]
  1610. X\begin{flushleft}
  1611. X{\tt @name} $<${\em object\/}$>$ \verb|=| $<${\em name\/}$>$ \\
  1612. X{\tt @name} $<${\em player\/}$>$ \verb|=| $<${\em name\/}$>$ $<${\em
  1613. Xpassword\/}$>$
  1614. X\index{name@\type{"@name}}
  1615. X\end{flushleft}
  1616. XChanges the name of the specified object.  This can also be used to
  1617. Xspecify a new direction list for an exit (see for example {\tt
  1618. X@open\/}).  For a player, it requires the player's password.
  1619. X
  1620. X\dorule
  1621. X
  1622. X\item[]
  1623. X\begin{flushleft}
  1624. X{\tt @ofail} $<${\em object\/}$>$ $[$ \verb|=| $<${\em message\/}$>$
  1625. X$]$
  1626. X\index{ofail@\type{"@ofail}}
  1627. X\end{flushleft}
  1628. XWithout a message argument, clears the others failure message on
  1629. X$<${\em object\/}$>$, otherwise sets it.  The others failure message,
  1630. Xprefixed by the player's name, is shown to others when the player
  1631. Xfails to use $<${\em object\/}$>$.
  1632. X
  1633. X\dorule
  1634. X
  1635. X\item[]
  1636. X\begin{flushleft}
  1637. X{\tt @open} $<${\em direction\/}$>$ $[$ {\tt;} $<${\em other-dir\/}$>$
  1638. X$]*$ $[$ {\tt =} $<${\em destination\/}$>$ $]$
  1639. X\index{open@\type{"@open}}
  1640. X\end{flushleft}
  1641. XCreates an unlinked exit in the specified direction(s).  You can also
  1642. Xspecify an exit to link the exit to.  Once created, you (or any other
  1643. Xplayer) may use the {\tt @link} command to specify the room to which
  1644. Xthe exit leads.  See also {\tt @name}.
  1645. X
  1646. X\dorule
  1647. X
  1648. X\item[]
  1649. X\begin{flushleft}
  1650. X{\tt @osuccess} $<${\em object\/}$>$ $[$ \verb|=| $<${\em
  1651. Xmessage\/}$>$ $]$
  1652. X\index{osuccess@\type{"@osuccess}}
  1653. X\end{flushleft}
  1654. XWithout a message argument, clears the others success message on
  1655. X$<${\em object\/}$>$, otherwise sets it.  The others success message,
  1656. Xprefixed by the player's name, is shown to others when the player
  1657. Xsuccessfully uses $<${\em object\/}$>$.
  1658. X
  1659. X\dorule
  1660. X
  1661. X\item[]
  1662. X\begin{flushleft}
  1663. X{\tt @password} $<${\em old\/}$>$ \verb|=| $<${\em new\/}$>$
  1664. X\index{password@\type{"@password}}
  1665. X\end{flushleft}
  1666. XSets a new password; you must specify your old password to verify your
  1667. Xidentity.
  1668. X
  1669. X\dorule
  1670. X
  1671. X\item[]
  1672. X\begin{flushleft}
  1673. X{\tt @set} $<${\em object\/}$>$ \verb|=| $<${\em flag\/}$>$ \\
  1674. X{\tt @set} $<${\em object\/}$>$ \verb|=| {\tt !}$<${\em flag\/}$>$
  1675. X\index{set@\type{"@set}}
  1676. X\end{flushleft}
  1677. XSets (first form) or resets (second form) $<${\em flag\/}$>$ on
  1678. X$<${\em object\/}$>$.  The current flags are \verb|dark|,
  1679. X\verb|link_ok|, \verb|sticky|, \verb|temple|, and \verb|wizard|.
  1680. X
  1681. X\dorule
  1682. X
  1683. X\item[]
  1684. X\begin{flushleft}
  1685. X{\tt @success} $<${\em object\/}$>$ \verb|=| $<${\em message\/}$>$
  1686. X\index{success@\type{"@success}}
  1687. X\end{flushleft}
  1688. XWithout a message argument, clears the success message on $<${\em
  1689. Xobject\/}$>$, otherwise sets it.  The success message is printed when
  1690. Xa player successfully uses $<${\em object\/}$>$.  Without $<${\em
  1691. Xmessage}$>$ it clears the success message.
  1692. X
  1693. X\dorule
  1694. X
  1695. X\item[]
  1696. X\begin{flushleft}
  1697. X{\tt @teleport} $<${\em object\/}$>$ {\tt =} $<${\em destination\/}$>$
  1698. X\index{teleport@\type{"@teleport}}
  1699. X\end{flushleft}
  1700. XTeleports the object to the specified destination.  You must either
  1701. Xcontrol the object or it's current location, and you must be able to
  1702. Xlink to the destination. You can only teleport objects from room to
  1703. Xroom, not into or out of someone's hand.
  1704. X
  1705. X\dorule
  1706. X
  1707. X\item[]
  1708. X\begin{flushleft}
  1709. X{\tt @unlink} $<${\em direction\/}$>$
  1710. X\index{unlink@\type{"@unlink}}
  1711. X\end{flushleft}
  1712. XRemoves the link on the exit in the specified $<${\em direction\/}$>$.
  1713. XYou must own the exit.  The exit may then be relinked by any player
  1714. Xusing the {\tt @link} command and ownership of the exit transfers to
  1715. Xthat player.
  1716. X
  1717. X\dorule
  1718. X
  1719. X\item[]
  1720. X\begin{flushleft}
  1721. X{\tt @unlock} $<${\em object\/}$>$
  1722. X\index{unlock@\type{"@unlock}}
  1723. X\end{flushleft}
  1724. XRemoves the lock on an object.
  1725. X
  1726. X\end{simple}
  1727. X
  1728. X\section{Miscellaneous commands}
  1729. X\label{sec:miscellaneous-commands}
  1730. X
  1731. X\begin{simple}
  1732. X
  1733. X\item[]
  1734. X\begin{flushleft}
  1735. X{\tt @stats}
  1736. X\index{stats@\type{"@stats}}
  1737. XShows current total of players, rooms, objects, exits.
  1738. X\end{flushleft}
  1739. X
  1740. X\end{simple}
  1741. X
  1742. X\section{Money}
  1743. X\label{sec:money}
  1744. X
  1745. XSome actions have an associated cost:
  1746. X\begin{center}
  1747. X\begin{tabular}{|l|p{4in}|}
  1748. X\hline
  1749. X\multicolumn{1}{|c|}{{\bf Action}} &
  1750. X\multicolumn{1}{c|}{{\bf Cost}} \\
  1751. X\hline
  1752. X\hline
  1753. X\hline
  1754. X{\tt kill} & 10 pennies or more \\
  1755. X\hline
  1756. X{\tt page} & 1 penny \\
  1757. X\hline
  1758. X{\tt @open} & 1 penny \\
  1759. X\hline
  1760. X{\tt @dig} & 10 pennies \\
  1761. X\hline
  1762. X{\tt @create} & 10 pennies (or more) \\
  1763. X\hline
  1764. X{\tt @link} & 1 penny, plus 1 penny to the previous owner if you
  1765. Xdidn't already own the exit. \\
  1766. X\hline
  1767. X\end{tabular}
  1768. X\index{kill@\type{kill}}
  1769. X\index{page@\type{page}}
  1770. X\index{open@\type{"@open}}
  1771. X\index{dig@\type{"@dig}}
  1772. X\index{create@\type{"@create}}
  1773. X\index{link@\type{"@link}}
  1774. X\end{center}
  1775. X
  1776. XYou get money by finding pennies, getting killed, having someone give
  1777. Xyou money, or by sacrificing a thing.  The sacrifice value of a thing
  1778. Xis $(\mbox{\rm cost of the thing} / 5 ) - 1$.
  1779. X
  1780. X\section{TinyMUD concepts}
  1781. X\label{sec:tinymud-concepts}
  1782. X
  1783. XAn {\em object} is either a player, room, thing, or exit.
  1784. X
  1785. XIn addition to the commands listed above there are some built in words
  1786. Xin {\tinymud}; {\tt me}\index{me@\type{me}} and {\tt
  1787. Xhere}\index{here@\type{here}}.  {\tt me} refers to your character or
  1788. Xplayer, and {\tt here} refers to the room you are in.  For example,
  1789. Xyou can use the \verb|@describe| command to give yourself a
  1790. Xdescription; as another example, in order to prevent yourself from
  1791. Xbeing robbed use {\tt @lock me = me\/}.
  1792. X
  1793. X\subsection{Success and the lack thereof}
  1794. X\label{sec:success-and-the-lack-thereof}
  1795. X
  1796. XWhen you can {\tt take} a thing, use an exit, or rob a player you are
  1797. Xsuccessfull in using that object.  The converse is true for failure.
  1798. XThe {\tt @success\/}, {\tt @osuccess\/}, {\tt @fail\/}, and {\tt
  1799. X@ofail} commands set the success and failure messages on objects.%
  1800. X\index{success@\type{"@success}}%
  1801. X\index{osuccess@\type{"@osuccess}}%
  1802. X\index{fail@\type{"@fail}}%
  1803. X\index{ofail@\type{"@ofail}}
  1804. X
  1805. X\subsection{Object strings}
  1806. X\label{sec:object-strings}
  1807. X
  1808. XEvery object has six strings:
  1809. X\begin{enumerate}
  1810. X\item
  1811. XName.  This is what you use with {\tt drop\/}, {\tt examine\/}, {\tt
  1812. Xget\/}, and so on.  You can also use the object's number (for example,
  1813. Xwhen two objects have the same name).
  1814. X
  1815. X\item
  1816. XDescription.  This is what is given when you use the {\tt look}
  1817. Xcommand.
  1818. X
  1819. X\item
  1820. XSuccess message.  This is what you see when you successfully use the
  1821. Xobject.
  1822. X
  1823. X\item
  1824. XOthers success message.  This is what the other players see when you
  1825. Xsuccessfully use the object.
  1826. X
  1827. X\item
  1828. XFailure message.  This is what you see when you fail to use an object.
  1829. X
  1830. X\item
  1831. XOthers failure message.  This is what the other players see when you
  1832. Xfail to use an object.
  1833. X\end{enumerate}
  1834. XThe maximum length of each string is 512 characters.
  1835. X
  1836. X\subsection{Object properties}
  1837. X\label{sec:object-properties}
  1838. X
  1839. XAs listed in the \verb|@set| command, objects can have any of the
  1840. Xfollowing properties:
  1841. X\begin{description}
  1842. X\item[{\tt dark}]
  1843. X\index{dark@\type{dark}}
  1844. XWhen a room has its {\tt dark} flag set you can't see things in it
  1845. Xwith the {\tt look} command.  When a thing or player has its {\tt
  1846. Xdark} flag set it can't be seen.  Only a wizard can set the {\tt dark}
  1847. Xflag on a thing or player.  Setting the {\tt dark} flag on exits
  1848. Xcurrently has no effect.
  1849. X
  1850. X\item[{\tt link{\ub}ok}]
  1851. X\index{linkok@\verb,link_ok,}
  1852. XYou can link to a room if you control it, or if the room has its
  1853. X\verb|link_ok| flag set.  Being able to link to a room means that you
  1854. Xcan set the homes\index{home} of things (or yourself) to that room,
  1855. Xand you can set the destination of exits to that room.  See also the
  1856. X{\tt @link} command for additional information on linking and
  1857. Xsection~\ref{sec:droptos} for droptos.  Setting the
  1858. X\verb|link_ok| flag on players, things, and exits currently has no
  1859. Xeffect.
  1860. X
  1861. X\item[{\tt sticky}]
  1862. X\index{sticky@\type{sticky}}
  1863. XWhen an object that has its {\tt sticky} flag set is dropped it
  1864. Ximmediately goes home.  When a room has its {\tt sticky} flag set its
  1865. Xdropto is delayed until the last person leaves the room.  Setting the
  1866. X{\tt sticky} flag on players and exits currently has no effect.
  1867. X
  1868. X\item[{\tt temple}]
  1869. X\index{temple@\type{temple}}
  1870. XWhen a room has its {\tt temple} flag set you can sacrifice things
  1871. Xthere and receive pennies for your sacrifices.  (See
  1872. Xsection~\ref{sec:money} for how many pennies you receive for your
  1873. Xsacrifices.)  Only a wizard can set this flag.  Setting this flag on
  1874. Xplayers, things, and exits currently has no effect.
  1875. X
  1876. X\item[{\tt wizard}]
  1877. X\index{wizard@\type{wizard}}
  1878. XWhen a player has its {\tt wizard} flag set they are a wizard.  Only a
  1879. Xwizard can set this flag.  Setting this flag on things, rooms, and
  1880. Xexits currently has no effect.
  1881. X
  1882. X\end{description}
  1883. X
  1884. XThe flags {\tt player\/}, {\tt room\/}, and {\tt exit} are set
  1885. Xautomatically when a player, room, or exit is created.  They cannot be
  1886. Xsubsequently unset or set with the \verb|@set| command.
  1887. X
  1888. X\subsection{Control}
  1889. X\label{sec:control}
  1890. X
  1891. XThere are three rules for determining control:
  1892. X\begin{enumerate}
  1893. X\item
  1894. XYou can control anything you own.
  1895. X\item
  1896. XA wizard can control anything.
  1897. X\item\label{item:unlinked-exit}
  1898. XAnybody can control an unlinked exit (even if it is locked).
  1899. X\end{enumerate}
  1900. XBuilders should watch out for item~\ref{item:unlinked-exit}.
  1901. X
  1902. X\subsection{Dropto's}
  1903. X\label{sec:droptos}
  1904. X
  1905. X\index{droptos}
  1906. XWhen the {\tt @link} command is used on a room, it sets a dropto
  1907. Xlocation for that room.  Any thing dropped in the room (if it is not
  1908. X{\tt sticky\/}; see above) will go to that location.  If the room has
  1909. Xits {\tt sticky\/} flag set the effect of the dropto will be delayed
  1910. Xuntil the last player leaves the room.  The special location {\tt
  1911. Xhome} may be used as a dropto, as in {\tt @link here = home\/}; in
  1912. Xthat case things dropped in the room will go to their
  1913. Xhomes\index{home@\type{home}}.  To remove the dropto on a room go into
  1914. Xthat room and use {\tt @unlink here\/}\index{here@\type{here}}.
  1915. X
  1916. X\subsection{Homes}
  1917. X\label{sec:homes}
  1918. X
  1919. X\index{home}
  1920. XEvery thing or player has a home.  For things, this is the location
  1921. Xthe thing returns to when sacrificed, when a player carrying it goes
  1922. Xhome, or when (if its {\tt sticky\/} flag is set) it is dropped.  For
  1923. Xplayers, this is where the player goes when they issue the {\tt home}
  1924. Xcommand.  Homes may be set using the {\tt @link} command; for example,
  1925. X{\tt @link donut =} $<${\em room-number\/}$>$ or {\tt @link me =}
  1926. X$<${\em room-number\/}$>$\index{me@\type{me}}.  Exits may also be
  1927. Xlinked to the special location {\tt home\/}; for example, {\tt @link
  1928. Xnorth = home\/}\index{home@\type{home}}.
  1929. X
  1930. X\subsection{Recycling}
  1931. X\label{sec:recycling}
  1932. X
  1933. XNothing can be destroyed in {\tinymud}, but it is possible to recycle
  1934. Xjust about anything.  The {\tt @name} command can be used to rename
  1935. Xobjects, making it easy to turn a silk purse into a sow's ear or vice
  1936. Xversa.  Extra exits can be unlinked and picked up by their owner using
  1937. Xthe {\tt get} command, and dropped like things using the {\tt drop}
  1938. Xcommand in any room controlled by the dropper.
  1939. X
  1940. X\subsection{Being killed}
  1941. X\label{sec:being-killed}
  1942. X
  1943. XWhen you are killed you return to your home and any items you were
  1944. Xcarrying return to their homes.  As a consolation you receive 50
  1945. Xpennies from the {\tinymud} Total Life Indemnity insurance
  1946. Xcompany.
  1947. X
  1948. X\section{Examples}
  1949. X\label{sec:examples}
  1950. X
  1951. XHere we present examples to demonstrate some of the features of
  1952. X{\tinymud}.
  1953. X
  1954. X\subsection{Success and failure messages}
  1955. X\label{sec:success-and-failure-messages}
  1956. X
  1957. XSuccess and failure messages are fairly straightforward.  Just
  1958. Xremember that for the messages set with {\tt
  1959. X@osuccess}\index{osuccess@\type{"@osuccess}} and {\tt
  1960. X@ofail}\index{ofail@\type{"@ofail}} the player's name is prefixed onto
  1961. Xthe message when it is printed, while the messages set with {\tt
  1962. X@success}\index{success@\type{"@success}} and {\tt
  1963. X@fail}\index{fail@\type{"@fail}} are printed as-is.
  1964. X
  1965. XPreviously we saw that you can use {\tt say}, \verb|"|, and \verb|:|
  1966. Xto display messages.  An older method for posing non sequiturs is to
  1967. Xset the others success message on yourself and then rob yourself.  For
  1968. Xexample, if your character is Betty and you do
  1969. X\index{say@\type{say}}
  1970. X\index{""@\type{""}}
  1971. X\index{:@\type{:}}
  1972. X\begin{verbatim}
  1973. X@osuccess me = starts picking her nose.
  1974. Xrob me
  1975. X\end{verbatim}
  1976. Xon your screen you'll see
  1977. X\begin{verbatim}
  1978. XYou stole a penny.
  1979. XBetty stole one of your pennies!
  1980. X\end{verbatim}
  1981. Xwhile the other players will see
  1982. X\begin{verbatim}
  1983. XBetty starts picking her nose.
  1984. X\end{verbatim}
  1985. XAn easier way to accomplish this is to simply do
  1986. X\begin{verbatim}
  1987. X:starts picking her nose.
  1988. X\end{verbatim}
  1989. Xthen both you and the others see
  1990. X\begin{verbatim}
  1991. XBetty starts picking her nose.
  1992. X\end{verbatim}
  1993. XWhen using \verb|"| and \verb|:| don't follow them with a space
  1994. Xbecause it will be included in the output; put the message right up
  1995. Xagainst the quotes or colon.
  1996. X
  1997. X\subsection{Making your home}
  1998. X\label{sec:making-your-home}
  1999. X
  2000. X\index{home}
  2001. XThe minimal steps for making your home are
  2002. X\begin{enumerate}
  2003. X\item
  2004. XMake the room for your home with the {\tt @dig} command.  Write down
  2005. Xthe room number in case the following step takes a long time.
  2006. X
  2007. X\item
  2008. X\label{item:exit}
  2009. XMake or acquire an exit.  In order to use the {\tt @open} command you
  2010. Xmust own the room that you are doing the {\tt @open} in.  The
  2011. Xalternative is to find a room with an exit that isn't linked and use
  2012. Xit.
  2013. X
  2014. X\item
  2015. XMake a link to your home.  Once you've made or found an unlinked exit
  2016. Xsimply use the {\tt @link} command to link the exit to your room.
  2017. X
  2018. X\item
  2019. X\label{item:exit-room}
  2020. XFind a room to which you can make a link in order to have an exit from
  2021. Xyour room (this is a room with the \verb|link_ok| flag set).  For the
  2022. Xsake of example we'll pretend the number of this room is 711; we'll be
  2023. Xusing it in step~\ref{item:exit-link}.  Without this you'd be able to
  2024. Xgo to your home but you wouldn't have any way to get out of it.
  2025. X
  2026. X\item
  2027. XSet the link from you to your home.  Go into your room and do
  2028. X\index{here@\type{here}}
  2029. X\index{link@\type{"@link}}
  2030. X\begin{verbatim}
  2031. X@link me = here
  2032. X\end{verbatim}
  2033. X
  2034. X\item
  2035. X\label{item:exit-link}
  2036. XMake the exit and link it to the destination
  2037. X\begin{verbatim}
  2038. X@open out
  2039. X@link out = #711
  2040. X\end{verbatim}
  2041. X(The \verb|#| isn't mandatory.)
  2042. X\end{enumerate}
  2043. X
  2044. XOf course there are probably various details that you would want to
  2045. Xtake care of in addition to the above steps.  For example, if you're
  2046. Xantisocial and want to prevent other people from using your home room
  2047. Xyou'd do
  2048. X\index{lock@\type{"@lock}}
  2049. X\begin{verbatim}
  2050. X@lock down = me
  2051. X\end{verbatim}
  2052. Xassuming that {\tt down} is the exit you made in step~\ref{item:exit}.
  2053. XAlong a similar vein you might not want other people linking to your
  2054. Xroom in which case you'd turn off the \verb|link_ok| flag on your
  2055. Xroom.  You might also set the description of your home room.  If you
  2056. Xown the exit you could also set the success, others success, fail, and
  2057. Xothers fail messages on the exit to your home.  Without the
  2058. Xdescriptions places and things are boring and uninteresting.
  2059. X
  2060. X\subsection{Lock key boolean examples}
  2061. X\label{sec:lock-key-boolean-examples}
  2062. X
  2063. XWhen using the {\tt @lock} command the key is either another object or
  2064. Xsome boolean combination of other objects.  If the key starts with a
  2065. X\verb|*| then that object must be a player.
  2066. X
  2067. XFor example, if a room has a direction {\tt out} and you want to
  2068. Xprevent players from carrying the object {\tt xyz} when they go out,
  2069. Xyou would use
  2070. X\begin{verbatim}
  2071. X@lock out = !xyz
  2072. X\end{verbatim}
  2073. Xor if you want to prevent the player Julia from using the {\tt out}
  2074. Xexit you would use
  2075. X\begin{verbatim}
  2076. X@lock out = !*Julia
  2077. X\end{verbatim}
  2078. XIf you want to prevent only Julia from going out with {\tt xyz} you
  2079. Xwould use
  2080. X\begin{verbatim}
  2081. X@lock out = ( *Julia & !xyz )
  2082. X\end{verbatim}
  2083. X
  2084. X\subsection{Ersatz commands}
  2085. X\label{sec:ersatz-commands}
  2086. X
  2087. XYou can make new commands by making an exit and then locking it to
  2088. Xsomething impossible to have and then assigning the failure and others
  2089. Xfailure messages to it.  For example, assume the following commands
  2090. Xhave been used
  2091. X\begin{verbatim}
  2092. X@open eat
  2093. X@link eat = here
  2094. X@lock eat = something_impossible
  2095. X@fail eat = You try to eat but only gag
  2096. X@ofail eat = tries to eat but instead gags
  2097. X\end{verbatim}
  2098. XThen when you use the command {\tt eat} the others in the room will
  2099. Xsee {\tt Betty tries to eat but instead gags} and you'll see {\tt You
  2100. Xtry to eat but only gag\/}.
  2101. X
  2102. XNote that this ``new command'' will only work in the room that you
  2103. Xmade it in.
  2104. X
  2105. X\clearpage
  2106. X
  2107. X\part*{Appendix}
  2108. X
  2109. X\appendix
  2110. X
  2111. X\section{Wizard commands}
  2112. X\label{sec:wizard-commands}
  2113. X
  2114. X\begin{simple}
  2115. X
  2116. X\item[]
  2117. X\begin{flushleft}
  2118. X{\tt @chown} $<${\em object\/}$>$ \verb|=| $<${\em player\/}$>$
  2119. X\index{chown@\type{"@chown}}
  2120. X\end{flushleft}
  2121. XChanges the ownership of $<${\em object\/}$>$ to $<${\em player\/}$>$.
  2122. X
  2123. X\dorule
  2124. X
  2125. X\item[]
  2126. X\begin{flushleft}
  2127. X{\tt @dump}
  2128. X\index{dump@\type{"@dump}}
  2129. X\end{flushleft}
  2130. XForces a dump of the database.  This command isn't really necessary
  2131. Xsince {\tt @shutdown} does one as well as the regular periodic dumps.
  2132. X
  2133. X\dorule
  2134. X
  2135. X\item[]
  2136. X\begin{flushleft}
  2137. X{\tt examine} $<${\em name\/}$>$ \\
  2138. X{\tt examine} {\tt \#}$<${\em number\/}$>$
  2139. X\index{examine@\type{examine}}
  2140. X\end{flushleft}
  2141. XPrint a detailed description of object specified by $<${\em name\/}$>$
  2142. Xor by $<${\em number\/}$>$.  All six strings listed in
  2143. Xsection~\ref{sec:object-strings} are printed.
  2144. X
  2145. XWhen $<${\em name\/}$>$ is a room or {\tt
  2146. Xhere}\index{here@\type{here}} it lists the owner, key, number of
  2147. Xpennies, the description, contents, and exits.  When $<${\em
  2148. Xname\/}$>$ is a direction lists the direction number, owner, key,
  2149. Xpennies, and destination.
  2150. X
  2151. X\dorule
  2152. X
  2153. X\item[]
  2154. X\begin{flushleft}
  2155. X{\tt @force} $<${\em victim\/}$>$ \verb|=| $<${\em command\/}$>$
  2156. X\index{force@\type{"@force}}
  2157. X\end{flushleft}
  2158. X
  2159. X\dorule
  2160. X
  2161. X\item[]
  2162. X\begin{flushleft}
  2163. X{\tt @newpassword} $<${\em player\/}$>$ \verb|=| $<${\em
  2164. Xpassword\/}$>$
  2165. X\index{newpassword@\type{"@newpassword}}
  2166. X\end{flushleft}
  2167. XChanges the password for $<${\em player\/}$>$.
  2168. X
  2169. X\dorule
  2170. X
  2171. X\item[]
  2172. X\begin{flushleft}
  2173. X{\tt @shutdown}
  2174. X\index{shutdown@\type{"@shutdown}}
  2175. X\end{flushleft}
  2176. XShuts down the {\tinymud} server.
  2177. X
  2178. X\dorule
  2179. X
  2180. X\item[]
  2181. X\begin{flushleft}
  2182. X{\tt @stats}
  2183. X\index{stats@\type{"@stats}}
  2184. X\end{flushleft}
  2185. XLists the total number of objects, which is the sum of the rooms,
  2186. Xexits, things, and players, giving the count for each one.
  2187. X
  2188. X\dorule
  2189. X
  2190. X\item[]
  2191. X\begin{flushleft}
  2192. X{\tt @teleport} $[$ $<${\em victim\/}$>$ \verb|=| $]$ $<${\em
  2193. Xdestination\/}$>$
  2194. X\index{teleport@\type{"@teleport}}
  2195. X\end{flushleft}
  2196. XTeleports the object to the specified destination.  Object can also be
  2197. X{\tt me\/}.\index{me@\type{me}}
  2198. X
  2199. X\dorule
  2200. X
  2201. X\item[]
  2202. X\begin{flushleft}
  2203. X{\tt @toad} $<${\em player\/}$>$
  2204. X\index{toad@\type{"@toad}}
  2205. X\end{flushleft}
  2206. XTurns $<${\em player\/}$>$ into an object.
  2207. X
  2208. X\dorule
  2209. X
  2210. X\item[]
  2211. X\begin{flushleft}
  2212. X{\tt @wall} $<${\em message\/}$>$
  2213. X\index{wall@\type{"@wall}}
  2214. X\end{flushleft}
  2215. XSend $<${\em message\/}$>$ to all players.
  2216. X
  2217. X\end{simple}
  2218. X
  2219. X\addcontentsline{toc}{part}{Index}
  2220. X
  2221. X\printindex
  2222. X
  2223. X\end{document}
  2224. END_OF_FILE
  2225. if test 28102 -ne `wc -c <'tinymud.tex'`; then
  2226.     echo shar: \"'tinymud.tex'\" unpacked with wrong size!
  2227. fi
  2228. # end of 'tinymud.tex'
  2229. fi
  2230. echo shar: End of archive 7 \(of 10\).
  2231. cp /dev/null ark7isdone
  2232. MISSING=""
  2233. for I in 1 2 3 4 5 6 7 8 9 10 ; do
  2234.     if test ! -f ark${I}isdone ; then
  2235.     MISSING="${MISSING} ${I}"
  2236.     fi
  2237. done
  2238. if test "${MISSING}" = "" ; then
  2239.     echo You have unpacked all 10 archives.
  2240.     echo ">>> now type 'sh joinspl.sh'"
  2241.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2242. else
  2243.     echo You still need to unpack the following archives:
  2244.     echo "        " ${MISSING}
  2245. fi
  2246. ##  End of shell archive.
  2247. exit 0
  2248.